/*
 * Copyright (c) Jan Šlahora (${USER}) - 2011.
 * Created in IntelliJ IDEA 10.5
 */

package text;


import com.sun.org.apache.bcel.internal.generic.RET;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.Locale;
import java.util.regex.Pattern;

/*
*   File DejCetnosti 
*   in package text
*   was created by slaha
*   on 30.11.11 at 15:56.
*
*/
public class DejCetnosti {

  public DejCetnosti() {
  }

  public CetnostZnaku dejCetnostZnaku (ArrayList<String> s, Boolean vel, Boolean bileZn) {
    return new CetnostZnaku(s, vel, bileZn);
  }

  public DelkaSlova dejDelkuSlova(ArrayList<String> s, boolean ignorovatCisla) {
    return new DelkaSlova(s, ignorovatCisla);
  }

  public SlovVeVete dejSlovVeVete(ArrayList<String> s, boolean ignorovatCisla) {
    return new SlovVeVete(s, ignorovatCisla);
  }

  public SlovVeVersi dejSlovVeVersi(ArrayList<String> s) {
    return new SlovVeVersi(s);
  }


public class CetnostZnaku implements Runnable{
  ArrayList<String> s=null;
  Thread t=null;
  boolean neignVelikost;
  boolean ignBileZnaky;
  HashMap<Character, Integer> hm = null;

  public CetnostZnaku(ArrayList<String> s, Boolean vel, Boolean bileZn){
    this.s=s;
    this.ignBileZnaky = bileZn;
    this.neignVelikost = vel;
    this.t= new Thread(this);
    run();
  }

  public HashMap<Character, Integer> getHm() {
    return hm;
  }

  private void dejCetnosti() {
    hm = new HashMap<Character, Integer>();

    for (String text : s) {
      for(int i=0;i<text.length();i++) {
        Character zn = dejZnak(text, i);
        if (zn==null) {
          continue;
        }

        if (dejZnak(text, i + 1) != null) {

          if (zn=='c' && dejZnak(text, i+1)=='h') {
            zn = 1;
            i++;
          }
        }
        //.. když už tam znak je, inkrementujeme jeho počet
        if (hm.containsKey(zn)) {
          hm.put(zn, hm.get(zn)+1);
        }
        //.. když tam není, vložíme ho s počtem 1
        else {
          hm.put(zn, 1);
        }
      }
    }
  }

  /**
   * Vrací znak ze stringu na pozici i
   * @param i pozice, na níž je požadovaný znak
   * @return znak na pozici i, není-li tam nic, příp. něco jiného než písmeno nebo číslice při ignBileZn=true, vrací  null
   */
  private Character dejZnak(String text, int i) {
    if (i>=text.length()) {
      return null;
    }
    Character zn = text.charAt(i);

    if (zn!=null) {
      //.. ignorujeme velikost písmen, převedeme na malá
      if (!neignVelikost) {
        zn = zn.toString().toLowerCase(new Locale("cs_CZ")).charAt(0);
      }

      //.. když ignorujeme bílé znaky, vrátíme místo něj null
      if (ignBileZnaky) {

        if (!(Character.isAlphabetic(zn))) {
          return null;
        }
      }
    }

    return zn;
  }

  @Override
  public void run() {
    this.dejCetnosti();
  }
}

public class DelkaSlova implements Runnable {
  ArrayList<String> s = null;
  Thread t = null;
  boolean ignCisla;
  HashMap<Integer, Integer> hm = null;

  public DelkaSlova(ArrayList<String> s, Boolean ignorovatCisla) {
    this.s = s;
    this.ignCisla = ignorovatCisla;
    this.t = new Thread(this);

  }

  public HashMap<Integer, Integer> getHm() {
    return hm;
  }

  private void dejCetnostiSlov() {
    hm = DejCetnosti.dejCetnostiSlov(s, ignCisla);
  }
  @Override
  public void run() {
    this.dejCetnostiSlov();
  }
}

  /**
   * Vrátí četnost slov dle jejich délky
   * @param s text, který analyzujeme
   * @param ignorovatCisla true - čísla se také počítají, false - čísla jsou ignorována
   * @return HashMap(délka slova, počet výskytů)
   */
  static HashMap<Integer, Integer> dejCetnostiSlov(ArrayList<String> s, boolean ignorovatCisla) {
    HashMap<Integer, Integer> hm = new HashMap<Integer, Integer>();


    for(String text : s) {
      String[] a = text.split(" ");

      for (int i = 0; i < a.length; i++) {
        if (dejSlovo(a[i], ignorovatCisla)) {
          int delka = a[i].length();
          if (ignorovatCisla) {
            if (!(Character.isAlphabetic(a[i].charAt(delka-1)))) {
              delka--;
            }
          } else {
            if (!(Character.isLetter(a[i].charAt(delka - 1)))) {
              delka--;
            }
          }
          if (hm.containsKey(delka)) {
            int hodnota = hm.get(delka);
            hm.put(delka, ++hodnota);
          } else {
            hm.put(delka, 1);
          }
        }
      }
    }

    return hm;
  }

  private static boolean dejSlovo(String slovo, boolean ignCisla) {
    if (ignCisla) {
      if (Pattern.matches("[a-zA-ZěščřžýáíéúůďťňĚŠČŘŽÝÁÉÚŮ]+[\\.:;,!\\?]*$", slovo)) {
        return true;
      } else {
        return false;
      }
      //.. když neignoruju čísla
    } else {
      if (Pattern.matches("[a-zA-Z0-9ěščřžýáíéúůďťňĚŠČŘŽÝÁÉÚŮ]+[\\.:;,!\\?]*$", slovo)) {
        return true;
      } else {
        return false;
      }
    }
  }

public class SlovVeVete implements Runnable {
  ArrayList<String> s = null;
  Thread t = null;
  boolean ignorovatCisla;
  HashMap<Integer, Integer> hm = null;

  public SlovVeVete(ArrayList<String> s, Boolean ignorovatCisla) {
    this.s = s;
    this.t = new Thread(this);
    this.ignorovatCisla = ignorovatCisla;
  }

  public HashMap<Integer, Integer> getHm() {
    return hm;
  }

  private void dejPocetSlovVeVete() {
    hm= DejCetnosti.dejPocetSlovVeVete(s, ignorovatCisla);
  }

  @Override
  public void run() {
    this.dejPocetSlovVeVete();
  }
}

  /**
   * Vrací počet slov ve větě
   * @param s Text, který analyzuju
   * @param ignorovatCisla true - počítat číslice jako slova, false - ignorovat je
   * @return HashMap(počet slov ve větě, počet výskytů)
   */
  static HashMap<Integer, Integer> dejPocetSlovVeVete(ArrayList<String> s, boolean ignorovatCisla) {
    HashMap<Integer, Integer> hm = new HashMap<Integer, Integer>();

    int pocet;
    int konec;
    char[] znaky = {'.', '?', '!', ':'};

    for (String  text : s) {
      int pocatek = 0;
      do {
        pocet = 0;
        String v = DejPocty.dejVetu(text.substring(pocatek), znaky);
        konec = pocatek + v.length();

        //.. zbavím se bílých znaků na začátku
        String veta = DejPocty.vymazBileZnaky(v);

        //.. rozdělím na slova
        String[] a = veta.split(" ");



        for (int i = 0; i < a.length; i++) {
          //.. když tam je slovo
          if (DejCetnosti.dejSlovo(a[i], ignorovatCisla)) {
            pocet++;
          }
        }

        if (hm.containsKey(pocet)) {
          int hodnota = hm.get(pocet);
          hm.put(pocet, ++hodnota);
        } else {
          hm.put(pocet, 1);
        }


        pocatek = konec;
      } while ((konec) < text.length() && konec > 0);
    }
    return hm;
  }


public class SlovVeVersi implements Runnable {
  ArrayList<String> s = null;
  Thread t = null;
  HashMap<Integer, Integer> hm = null;

  public SlovVeVersi(ArrayList<String> s) {
    this.s = s;
    this.t = new Thread(this);
    run();
  }

  public HashMap<Integer, Integer> getHm() {
    return hm;
  }

  private void dejPocetSlovVeVersi() {
    hm = DejCetnosti.dejPocetSlovVeVersi(s);
  }

  @Override
  public void run() {
    this.dejPocetSlovVeVersi();
  }

  public double dejPrumerHM() {
    if (hm.size() > 0) {
      double pocetSlov = 0;
      int pocetVersu = 0;

      for (int i : hm.keySet()) {
        if (hm.get(i) > 0) {
          pocetSlov += (i * hm.get(i));
          pocetVersu += hm.get(i);
        }
      }

      return pocetSlov / (double) pocetVersu;
    }

    return -1d;
  }
}

  /**
   * Vrací počet slov ve větě
   *
   * @param s              Text, který analyzuju
   * @return HashMap(počet slov ve větě, počet výskytů)
   */
  static HashMap<Integer, Integer> dejPocetSlovVeVersi(ArrayList<String> s) {
    HashMap<Integer, Integer> hm = new HashMap<Integer, Integer>();

    for (String text : s) {
      String[] verse = text.split("\r\n|\r|\n");

      for (String vers : verse) {
        if (vers.length() != 0) {
          String versBezMezer = DejPocty.vymazBileZnaky(vers);

          String[] slova = versBezMezer.split(" ");

          int pocet = 0;
          for (int i = 0; i < slova.length; i++) {
            //.. když tam je slovo
            if (DejCetnosti.dejSlovo(slova[i], true)) {
              pocet++;
            }
          }

          if (hm.containsKey(pocet)) {
            int hodnota = hm.get(pocet);
            hm.put(pocet, ++hodnota);
          } else {
            hm.put(pocet, 1);
          }
        }
      }
    }
    return hm;
  }
}